/**
 * Copyright (c) 2011 James Wendel
 *
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package nlworks.wowapi.util;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;
import org.apache.http.Header;
import org.apache.http.HeaderElement;
import org.apache.http.HttpEntity;
import org.apache.http.HttpException;
import org.apache.http.HttpRequest;
import org.apache.http.HttpRequestInterceptor;
import org.apache.http.HttpResponse;
import org.apache.http.HttpResponseInterceptor;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.GzipDecompressingEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicHeader;
import org.apache.http.protocol.HttpContext;

public class ConnectionManager {

	HttpClient httpClient;

	public ConnectionManager() {
		DefaultHttpClient httpclient = new DefaultHttpClient();
		httpclient.addRequestInterceptor(new HttpRequestInterceptor() {

			public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException {
				if (!request.containsHeader("Accept-Encoding")) {
					request.addHeader("Accept-Encoding", "gzip");
				}
			}

		});

		httpclient.addResponseInterceptor(new HttpResponseInterceptor() {

			public void process(final HttpResponse response, final HttpContext context) throws HttpException, IOException {
				HttpEntity entity = response.getEntity();
				Header ceheader = entity.getContentEncoding();
				if (ceheader != null) {
					HeaderElement[] codecs = ceheader.getElements();
					for (int i = 0; i < codecs.length; i++) {
						if (codecs[i].getName().equalsIgnoreCase("gzip")) {
							response.setEntity(new GzipDecompressingEntity(response.getEntity()));
							return;
						}
					}
				}
			}

		});
		httpClient = httpclient;
	}

	public String sendRequest(String url, long lastModified, String publicKey, String privateKey) {

		String ret = null;
		System.out.println("URL to send: " + url);
		
		if (publicKey != null && publicKey.length() > 0 && privateKey != null && privateKey.length() > 0) {
			// generateSignature(St)
			// TODO private key signing of requests

//			String stringToSign = urlConnection.getRequestMethod() + "\n" + dateStr + "\n" + UrlPath + "\n";
//			String sig = generateHmacSHA1Signature(stringToSign, privateKey);
//			try {
//				urlConnection.setRequestProperty("Authorization", "BNET" + " " + publicKey + ":" + sig);
//				urlConnection.setRequestProperty("Date", dateStr);
//				if (lastModified != 0)
//					urlConnection.setIfModifiedSince(lastModified);
//			} catch (IllegalStateException e) {
//				e.printStackTrace();
//			}
		}

		HttpGet httpGet = new HttpGet(url);
		if (lastModified > 0) {
			httpGet.addHeader(new BasicHeader("If-Modified-Since", Long.toString(lastModified)));
		}
		
		try {
			HttpResponse response = httpClient.execute(httpGet);
			System.out.println("Resp Status: " + response.getStatusLine());
			BufferedReader reader = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
            StringBuffer sb = new StringBuffer(1024);
			while (reader.ready()) {
                sb.append(reader.readLine()).append('\n');
            }
			ret = sb.toString();
			System.out.println("Resp Data: " + ret);
		} catch (ClientProtocolException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		return ret;
	}

	private static String generateSignature(String key, String data) throws GeneralSecurityException, IOException {
		byte[] hmacData = null;
		SecretKeySpec secretKey = new SecretKeySpec(key.getBytes("UTF-8"), "HmacSHA1");
		Mac mac = Mac.getInstance("HmacSHA1");
		mac.init(secretKey);
		hmacData = mac.doFinal(data.getBytes("UTF-8"));
		return Base64.encodeBase64String(hmacData);
	}
}
